/**
 * base64ToFile
 * @param {string} [data] string
 * @param {string} [filename] string
 * @returns {File} file文件
 */
export function base64ToFile(data: string, filename = 'base64ToFile') {
  // 将base64转换为文件
  const arr = data.split(',')
  const mime = arr?.[0]?.match?.(/:(.*?);/)?.[1]
  const bstr = atob(arr[1])
  let n = bstr.length
  const u8arr = new Uint8Array(n)
  while (n--)
    u8arr[n] = bstr.charCodeAt(n)

  return new File([u8arr], filename, { type: mime })
}
/**
 * 文件下载
 * @param file File
 */
export function downloadFile(file: File) {
  const aTag = document.createElement('a') // 创建一个a标签
  aTag.download = file.name
  const href = URL.createObjectURL(file) // 获取url
  aTag.href = href
  aTag.click()
  URL.revokeObjectURL(href) // 释放url
}

/**
 * 文件下载
 * @param res 完整响应
 */
export function downLoadFileStream(
  res: any,
  options: {
    fileName?: string
    ext?: string
    callback?: () => void
  },
) {
  const contentType = res.headers['content-type'] ?? res.headers['Content-Type']
  //  返回异常信息时请求头含'json'字样

  if (contentType?.includes('json')) {
    const reader = new FileReader()
    reader.readAsText(res.data, 'utf-8')
    // 读取异常信息
    reader.onload = () => {
      if (reader) {
        const resStr = reader?.result as string
        const jsonObj = JSON.parse(resStr)
        throw new Error(jsonObj.msg)
      }
    }
  }
  else {
    // 正常返回文件流是size通常大于0
    if (res.data.size) {
      // 读取后台返回的文件名
      const requestFileName
        = res.headers['content-disposition'] ?? res.headers['Content-Disposition']
      let fileName = ''
      let extension = ''
      if (requestFileName) {
        fileName = decodeURIComponent(
          requestFileName.slice(
            requestFileName.indexOf('=') + 1,
            requestFileName.lastIndexOf('.'),
          ),
        )
        // 读取后台返回的文件扩展名
        extension = requestFileName.slice(
          requestFileName.lastIndexOf('.'),
          requestFileName.length,
        )
      }
      else {
        fileName = options?.fileName ?? Date.now().toString()
        extension = options?.ext ?? '.error'
      }
      const r = new FileReader()
      // 通过实现a标签点击下载文件
      r.onload = function () {
        fileName = fileName + extension
        const link = document.createElement('a')
        const blob = new Blob([res.data])
        link.style.display = 'none'
        link.href = URL.createObjectURL(blob)
        link.download = fileName
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        options?.callback && options.callback()
      }
      r.readAsText(res.data)
    }
    else {
      throw new Error('Error, 后台无文件流返回')
    }
  }
}

/**
 * @description 根据json的地址下载json
 * @param {string} url json地址
 * @param {string} [name] 下载的文件名
 * @return {void}
 */
export function downloadJsonFile(url: string, name?: string) {
  return new Promise<void>((resolve, reject) => {
    // 创建一个新的 XMLHttpRequest 对象
    const xhr = new XMLHttpRequest()

    // 设置请求的数据类型为 JSON
    xhr.responseType = 'json'

    // 发送 HTTP 请求
    xhr.open('GET', url)
    xhr.send()

    // 当请求完成时，执行以下操作
    xhr.onload = function () {
      // 将 JSON 数据转换为字符串
      const jsonString = JSON.stringify(xhr.response)

      // 创建一个新的 Blob 对象
      const blob = new Blob([jsonString], { type: 'application/json' })

      // 创建一个新的链接
      const link = document.createElement('a')
      link.href = URL.createObjectURL(blob)

      // 设置链接的下载属性
      link.download = name ?? 'data' + '.json'

      // 将链接添加到页面中并点击它
      document.body.appendChild(link)
      link.click()

      // 释放链接所占用的内存
      URL.revokeObjectURL(link.href)
      document.body.removeChild(link)
      resolve()
    }
    xhr.onerror = function () {
      reject(new Error('下载失败'))
    }
  })
}

/**
 * 获取文件名的后缀
 * @param {string} [fileName] 文件名
 * @return {string} suffix:'.png'
 */
export function getSuffix(fileName: string): string {
  const index = fileName.lastIndexOf('.')
  return fileName.slice(index)
}

/**
 * 从url中获取文件名 + 后缀 如：http://asdasd/asdsad/asdsad/阿萨德.txt  =>  阿萨德.txt
 * @param {string} [val]
 * @return {string}
 */
export function getFileName(val: string): string {
  return val.slice(Math.max(0, val.lastIndexOf('/') + 1))
}
